package com.example.demo.controller; /**
 * 引入静态方法ok()
 */
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.Date;

import static org.springframework.web.reactive.function.server.ServerResponse.ok;

/**
 * @author 咸鱼
 * @date 2018/6/28 16:38
 */
@Component
public class TimeHandler {
    /**
     * 在响应式编程中，请求和响应不再是HttpServletRequest和HttpServletResponse，而是变成了ServerRequest和ServerResponse
     * @param request 请求
     * @return Mono和Flux主要用于响应式编程的“异步”数据流处理，不像我们以前直接返回String/List<T>....，而是直接包装成
     *         Mono和Flux对象。见文知意，Mono主要用于返回单个数据，Flux用于返回多个数据。比如我们要根据id查询某个User，
     *         那返回的肯定就是一个User，那么需要包装成Mono<User>；若我们需要获取所有User，这是一个集合，我们需要包装成
     *         Flux<User>。这里的单个数据并不是指一个数据，而是指封装好的一个对象；多个数据就是多个对象
     *         ServerRequest request, ServerResponse response
     */
    public Mono<ServerResponse> sendTimePerSec(ServerRequest request){
            //MediaType.TEXT_EVENT_STREAM表示Content-Type为text/event-stream，即SSE；
            return ok().contentType(MediaType.TEXT_EVENT_STREAM)
                    //利用interval生成每秒一个数据的流
                    .body(Flux.interval(Duration.ofSeconds(1))
                            /*
                             * map()：可以将数据元素进行转换/映射，得到一个新元素
                             * map接受一个“Function的函数式接口”为参数，这个函数式的作用是定义转换操作的策略。
                             * Function函数式接口：接受一个输入参数，返回一个结果。参数与返回值的类型可以不同，
                             *                     说白了就是一个lambda表达式，“->”前面的是参数，“->”后面
                             *                     的是方法体，若可以直接返回，则省略return。
                             */
                            .map(l -> new SimpleDateFormat("HH-mm-ss").format(new Date()))
                            ,String.class);
    }
}